/**
 * @brief 拨号模块.开机自动启动，设置模块的相关参数，特别是通讯层的相关参数，都应该在这个模块中完成.
 * @version 1.0
 * @date 2018-3-16
 * @author 宋炜
 */

#ifndef __DIAL_HPP__
#define __DIAL_HPP__

#include "ql_oe.h"
#include <string>
#include <iostream>
#include <atomic>

#if defined( __USE_MEMPOOL__)
#    include <jemalloc/jemalloc.h>
#endif

class ec20dial
{
public:
	// 网络类型定义
        enum sim_type{ _2G , _3G , _4G , _5G , __NW_UNKNOWN};
	//               移动   电信   联通 ,  不明运营商
	enum sim_vendor{ CMCC , CTCC , CUCC , VENDOR_UNKNOW };
	enum err_code{
		ERR_SIM_BASE = -1000,          // 占位
		ERR_NO_SIM,                    // sim 卡不存在
		ERR_SIM_BUSY,                  // SIM卡被占用
		ERR_SET_APN,                   // 设置APN错误
		ERR_GET_IMSI,                  // 读取IMSI错误
		ERR_NO_SIGNAL,                 // 检测不到信号
		ERR_SIM_UNKNOW,                // sim 卡不明错误
		ERR_NW_NOT_REG,                // 网络没有注册
		ERR_NW_UNKNOWN,                // 不明网络错误
		ERR_NW_DENIED,                 // 网络拒绝链接
		OK = 0
	};
private:
	err_code    m_error;                 // 错误编号
	bool        is_apn;                  // 是否开启apn
	bool        auto_2g;                 // 如果4g信号不好，是否可以降级到2g
	sim_vendor  vendor;                  // 网络运营商
	std::string user;                    // APN 用户
	std::string paswd;                   // APN 密码
private:
	/**
	 * @brief 检查SIM卡型号
	 */
	void check_sim();
	/**
	 * @brief 设置VPN参数
	 */
	bool set_apn();
	/**
	 * @brief 检查SIM卡提供商
	 * @exception 操作失败抛出ERR_GET_IMSI
	 * @return 成功操作返回对应的运行商编号；
	 * @note 运行商编号只面向国内3大运营商
	 */
	sim_vendor check_vendor();
	/**
	 * @brief 检查信号强度
	 * @return 返回信号强度。如果信号强度为99表示无法检测到信号
	 */
	int check_csq();
public:
	ec20dial();
	virtual ~ec20dial();
        /**
         * 启动运行。检查信号，SIM卡情况，如果一切正常则进行拨号
         */
	int run();
	/**
	 * @brief 获取SIM卡的网络提供商
	 */
	sim_vendor getVendor(){ return vendor; }
	/**
	 * @brief 检查注册网络类型
	 */
	static sim_type check_radio();
	/**
	 * @brief 获取SIM卡ICCID
	 */
	static std::string GetICCID();
	/**
	 * @brief 获取模块IMEI
	 */
	static std::string GetIMEI();
};
#endif
